package com.doge.walknovel.core.account

import android.app.Activity
import android.content.Intent
import androidx.lifecycle.MutableLiveData
import com.doge.wnpro.R
import com.doge.walknovel.analysis.analysisEvent
import com.doge.walknovel.analysis.login_google
import com.doge.walknovel.core.base.LoadStatus
import com.doge.walknovel.utils.appContext
import com.doge.walknovel.utils.getString
import com.doge.walknovel.utils.isMainThread
import com.doge.walknovel.utils.log
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.auth.api.signin.GoogleSignInOptions


object GoogleLoginHelper {
    private val clientId by lazy { getString(R.string.server_client_id) }
    private const val REQUEST_CODE = 322

    interface Callback {
        fun onResult(isSuccess: Boolean, data: GoogleUser?, error: String?)
    }

    private val loading = MutableLiveData<LoadStatus>()
    private val listeners = mutableListOf<Callback>()

    fun registerCallback(callback: Callback) {
        if (!listeners.contains(callback)) listeners.add(callback)
    }

    fun unregisterCallback(callback: Callback) {
        if (listeners.contains(callback)) listeners.remove(callback)
    }

    fun login(activity: Activity) {
        require(isMainThread())
        analysisEvent(login_google)

        val googleSignInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .requestIdToken(clientId)
            .requestProfile()
            .build()

        val mGoogleSignInClient = GoogleSignIn.getClient(appContext, googleSignInOptions)
        val signInIntent = mGoogleSignInClient.signInIntent
        activity.startActivityForResult(signInIntent, REQUEST_CODE)
    }

    fun logout() {
        require(isMainThread())

        val googleSignInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .requestIdToken(clientId)
            .requestProfile()
            .build()

        val signInClient = GoogleSignIn.getClient(appContext, googleSignInOptions)
        signInClient.signOut()
            .addOnCompleteListener {
                signInClient.revokeAccess()
                    .addOnCompleteListener {
                        log("The google account and the app are completely disconnected")
                    }
            }
    }

    fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode != REQUEST_CODE) return
        require(isMainThread())
        loading.value = LoadStatus.LOADING
        try {
            val account: GoogleSignInAccount? =
                GoogleSignIn.getSignedInAccountFromIntent(data).result
            val user = GoogleUser.from(account)
            if (user != null) {
                listeners.forEach { it.onResult(true, user, null) }
                loading.value = LoadStatus.SUCCESS
            } else {
                listeners.forEach {
                    it.onResult(false, null, "empty user info. ")
                }
                loading.value = LoadStatus.FAILURE
            }
        } catch (e: Throwable) {
            e.printStackTrace()
            listeners.forEach {
                it.onResult(false, null, "login failure ${e.message}")
            }
            loading.value = LoadStatus.FAILURE
        }
    }
}